package com.yfp.client.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.yfp.client.domain.*;
import com.yfp.client.domain.*;
import com.yfp.client.domain.vo.OutletVO;
import com.yfp.client.mapper.MarCouponMapper;
import com.yfp.client.mapper.MarCouponPositionMapper;
import com.yfp.client.service.*;
import com.yfp.common.core.constant.CacheConstants;
import com.yfp.client.service.*;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Description: 优惠券
 * 
 * @CreateDate: 2024/7/16 19:02
 * @UpdateUser: 
 * @UpdateDate: 2024/7/16 19:02
 * @UpdateRemark: 暂无修改
 * @Version: 1.0
 */
@Slf4j
@Service
public class MarCouponServiceImpl implements MarCouponService {
    @Autowired
    private MarCouponMapper marCouponMapper;
    @Autowired
    private MarCouponPositionMapper marCouponPositionMapper;
    @Autowired
    private MachineService machineService;
    @Autowired
    private AreaService areaService;
    @Autowired
    private PositionService positionService;
    @Resource
    private RedissonClient redissonClient;
    @Resource
    private MarCouponPackDetailsService marCouponPackDetailsService;

    /**
     * 查最后的弹窗优惠券
     *
     * @param popup
     * @return
     */
    @Override
    public MarCoupon findLastByPopup(Integer popup) {
        return marCouponMapper.findLastByPopup(popup);
    }

    /**
     * 领券中心
     *
     * @return
     */
    @Override
    public List<MarCoupon> validList(String clientId, String cityName) {
        //new 提醒
        RBloomFilter<Object> bloomFilter = redissonClient.getBloomFilter(CacheConstants.MINAPP_COUPON_NEW_ICON_KEY + clientId);
        bloomFilter.delete();
        bloomFilter.tryInit(1000000, 0.03);
        List<MarCoupon> marCoupons = marCouponMapper.validList(clientId, cityName);
        List<Long> collect = marCoupons.stream().map(marCoupon -> marCoupon.getId()).collect(Collectors.toList());
        log.info("validList:clientId:{},city:{}", clientId, cityName);
        log.info("validList:clientId:{},marCouponIds:{}", clientId, collect);
        for (MarCoupon marCoupon : marCoupons) {
            bloomFilter.add(marCoupon.getId());
        }
        return marCoupons;
    }

    /**
     * 修改剩余数量
     *
     * @param id
     */
    @Override
    public void editSurplusCount(Long id) {
        marCouponMapper.editSurplusCount(id);
    }

    @Override
    public MarCoupon findById(Long id) {
        return marCouponMapper.findById(id);
    }

    @Override
    public List<MarCoupon> findByIds(List<Long> ids) {
        if (CollUtil.isEmpty(ids)) {
            return List.of();
        }
        return marCouponMapper.findByIds(ids);
    }

    @Override
    public List<OutletVO> getOutlets(Long couponId) {
        MarCoupon marCoupon = marCouponMapper.findById(couponId);
        if (marCoupon.getPosition() != 1 && marCoupon.getPosition() != 3) {
            return null;
        }
        // 限制点位
        List<MarCouponPosition> marCouponPositions = marCouponPositionMapper.selectByMarCouponId(couponId);
        List<String> positionIds = marCouponPositions.stream().map(marCouponPosition -> marCouponPosition.getPositionId()).collect(Collectors.toList());

        // 点位
        List<Position> positions = positionService.findListByIdIn(positionIds);
        Map<String, Position> positionMap = positions.stream().collect(Collectors.toMap(Position::getPositionId, Function.identity(), (key1, key2) -> key2));
//        Map<String, List<Position>> positionMapAreaId = positions.stream().collect(Collectors.groupingBy(Position::getAreaId));
        List<String> areaIds = positions.stream().map(position -> position.getAreaId()).collect(Collectors.toList());
        // 区域
        List<Area> areas = areaService.findListByIdIn(areaIds);
        // 设备
        List<Machine> machines = machineService.findByPositionIdIn(positionIds);
        Map<String, List<Machine>> machineMapAreaId = machines.stream().collect(Collectors.groupingBy(Machine::getAreaId));

        // 组装区域数据
        Map<String, List<String>> cityMap = new HashMap<>();
        List<String> cityAreaIds = null;
        for (Area area : areas) {
            String cityName = area.getName().split("/")[1];
            if (null == cityMap.get(cityName)) {
                cityAreaIds = new ArrayList<>();
            } else {
                cityAreaIds = cityMap.get(cityName);
            }
            cityAreaIds.add(area.getAreaId());
            cityMap.put(cityName, cityAreaIds);
        }

        // 组装返回数据
        List<OutletVO> outletVOS = new ArrayList<>();
        OutletVO outletVO = null;
        for (String cityName : cityMap.keySet()) {
            outletVO = new OutletVO();
            outletVO.setCityName(cityName);
            List<String> cityIds = cityMap.get(cityName);
            List<OutletVO.Child> childs = new ArrayList<>();
            OutletVO.Child child = null;
            for (String cityId : cityIds) {
                if (!CollUtil.isEmpty(machineMapAreaId) && machineMapAreaId.containsKey(cityId)) {
                    for (Machine machine : machineMapAreaId.get(cityId)) {
                        child = new OutletVO.Child(positionMap.get(machine.getPositionId()).getPositionId(),
                                positionMap.get(machine.getPositionId()).getPositonName(),
                                machine.getMachineId(),
                                machine.getMachineName()
                        );
                        childs.add(child);
                    }
                }
            }
            outletVO.setChilds(childs);
            outletVOS.add(outletVO);
        }
        return outletVOS;
    }

    @Override
    public List<MarCoupon> getClientCouponListByStatus(Integer status) {
        return marCouponMapper.getClientCouponListByStatus(status);
    }

    @Override
    public List<MarCoupon> listByCouponPackId(Long couponPackId) {
        List<MarCouponPackDetails> marCouponPackDetails = marCouponPackDetailsService.findByCouponPackId(couponPackId);
        List<Long> couponIds = marCouponPackDetails.stream().map(item -> item.getCouponId()).collect(Collectors.toList());
        return marCouponMapper.findByIds(couponIds);
    }


}